package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Slf4j
@RestController()
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private RedisTemplate redisTemplate;


    @PostMapping
    public R saveWithFlavor(@RequestBody DishDto dto) {
        log.info("新增菜品dto:{}", dto);
        dishService.saveWithFlavor(dto);
        //添加清理缓存的逻辑
        String key = "dish_" +dto.getCategoryId() +"_"+"null" ;
        redisTemplate.delete(key);
        return R.success("添加成功");
    }
     /*   @GetMapping("/page")
     public R page(Integer page,Integer pageSize,String name) {
     Page pageInfo = new Page(page,pageSize);
     LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
     lqw.like(StringUtils.isNotEmpty(name),Dish::getName,name);//模糊匹配name
     lqw.orderByDesc(Dish::getUpdateTime);
     dishService.page(pageInfo,lqw);//放不进去带泛型的page参数
     return R.success(pageInfo);
     }*/

    /*
     * 根据条件分页查询
     */

    /**
     * 菜品分页查询-方案一
     */
   /* @GetMapping("/page")
    public R page(int page, int pageSize, String name) {
        Page<DishDto> pageInfo = dishService.pageByName(page, pageSize, name);
        return R.success(pageInfo);
    }*/
    @GetMapping("/page")
    public R page(int page, int pageSize, String name) {
        //查询单表基本数据
        //构建分页
        Page<Dish> pageInfo = new Page<>(page, pageSize);
        //构建条件
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        //根据名称模糊查询
        lqw.like(StringUtils.isNotEmpty(name), Dish::getName, name);
        //根据修改时间倒叙排序
        lqw.orderByDesc(Dish::getUpdateTime);
        //执行查询
        dishService.page(pageInfo, lqw);
        //<!---------------------------------------------------->
        Page<DishDto> resultPage = new Page<>();

        List<Dish> dishList = pageInfo.getRecords(); //用集合对单表数据封装
        //获取集合中所有菜品中的分类id
        /*
        Set<Long> categoryIdList = dishList.stream().map(Dish::getCategoryId).collect(Collectors.toSet());
        //根据id集合查询所有的分类 select * from category where id in (?,?,...)
        List<Category> categoryList = categoryService.listByIds(categoryIdList);
        //将List集合转换成Map  key:分类id  value:分类名称
        Map<Long, String> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getId, Category::getName));
*/
        List<DishDto> dtoList = dishList.stream().map(dish -> {
            DishDto dto = new DishDto();
            BeanUtils.copyProperties(dish, dto);//将dish中的数据拷贝至dto
            //设置分类名称
            Category category = categoryService.getById(dto.getCategoryId());
            dto.setCategoryName(category.getName());
            return dto;
        }).collect(Collectors.toList());

        resultPage.setRecords(dtoList);//把新的数据集设置到resultPage
        resultPage.setTotal(pageInfo.getTotal());//把总数据量设置到resultPage

        return R.success(resultPage);
    }

    /**
     * 根据Id查
     */
    @GetMapping("/{id}")
    public R get(@PathVariable Long id) {
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 根据Id修改
     */
    @PutMapping
    @Transactional
    public R update(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        dishService.updateWithFlavor(dishDto);
        //添加清理缓存的逻辑
        String key = "dish_" +dishDto.getCategoryId() +"_"+"null" ;
        redisTemplate.delete(key);
        return R.success("修改成功");
    }


    @GetMapping("/list")
    public R list(Dish dish) {
        String name = dish.getName();//菜品名称
        Long categoryId = dish.getCategoryId();//菜品分类id
        String key = "dish_" + dish.getCategoryId() + "_" + dish.getName();//菜品分类id和名称
        //先从redis中获取缓存数据
        List<DishDto> dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
        if (dishDtoList != null) {
            //如果存在，直接返回，无需查询数据库
            return R.success(dishDtoList);
        }
        //构建条件
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        //查询状态为1的数据
        lqw.eq(Dish::getStatus, 1);
        //根据菜品名称模糊查询
        lqw.like(StringUtils.isNotEmpty(name), Dish::getName, name);
        //根据菜品分类id精确查询
        lqw.eq(categoryId != null, Dish::getCategoryId, categoryId);
        //排序：修改时间倒叙排序
        lqw.orderByDesc(Dish::getUpdateTime);
        //发起查询
        List<Dish> list = dishService.list(lqw);
//        return R.success(list);
        //将List<Dish> 转换为 List<DishDto>
//        List<DishDto> resultList = list.stream().map(dishItem -> {
        dishDtoList = list.stream().map(dishItem -> {
            DishDto dto = new DishDto();
            //将dishItem 拷贝给dto
            BeanUtils.copyProperties(dishItem, dto);
            //查询当前菜品的口味信息
            //select * from dish_flavor where dish_id=?
            LambdaQueryWrapper<DishFlavor> flavorLqw = new LambdaQueryWrapper<>();
            flavorLqw.eq(DishFlavor::getDishId, dishItem.getId());
            List<DishFlavor> dishFlavorList = dishFlavorService.list(flavorLqw);
            //把当前菜品口味集合设置到dto中
            dto.setFlavors(dishFlavorList);
            return dto;
        }).collect(Collectors.toList());
        //缓存改造  写回Redis
        redisTemplate.opsForValue().set(key, dishDtoList, 1, TimeUnit.HOURS);
        return R.success(dishDtoList);
    }

    /*根据id批量删除*/
    @DeleteMapping
    public R deleteById(@RequestParam List<Long> ids) {
        dishService.deleteById(ids);
        //清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*"); //获取所有以dish_xxx开头的key
        redisTemplate.delete(keys); //删除这些key
        return R.success("删除成功");
    }

    @PostMapping("/status/{status}")
    public R status(@PathVariable Integer status, @RequestParam List<Long> ids) {
        dishService.updateByStatus(status, ids);
        for (Long id : ids) {
            Dish dish = dishService.getById(id);
            Long categoryId = dish.getCategoryId();
            //添加清理缓存的逻辑
            String key = "dish_" +categoryId +"_"+"null" ;
            redisTemplate.delete(key);
        }

        return R.success("菜品状态已经更改成功");
    }
}
